use bytesio::bytes_errors::{BytesReadError, BytesWriteError};
use failure::{Backtrace, Fail};
use std::fmt;

// 解包错误类型
#[derive(Debug, Fail)]
pub enum UnpackErrorValue {
    // 字节读取错误
    #[fail(display = "bytes read error: {}", _0)]
    BytesReadError(BytesReadError),
    // 未知的读取状态
    #[fail(display = "unknown read state")]
    UnknownReadStateError,
    // 空的 Chunk 数据
    #[fail(display = "empty chunks")]
    EmptyChunksError,
    // 无法解析数据
    #[fail(display = "cannot parse")]
    CannotParseError,
}

#[derive(Debug)]
pub struct UnpackError {
    pub value: UnpackErrorValue,
}

// 实现从 'UnpackErrorValue' 到 'UnpackError' 的转换
impl From<UnpackErrorValue> for UnpackError {
    fn from(value: UnpackErrorValue) -> Self {
        UnpackError { value }
    }
}

// 实现从 'BytesReadError' 到 'UnpackError' 的转换
impl From<BytesReadError> for UnpackError {
    fn from(error: BytesReadError) -> Self {
        UnpackError {
            value: UnpackErrorValue::BytesReadError(error),
        }
    }
}

// 实现 'fmt::Display' trait，用于格式化 'UnpackError' 的输出
impl fmt::Display for UnpackError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.value, f)
    }
}

// 实现 'Fail' trait，用于错误处理链
impl Fail for UnpackError {
    fn cause(&self) -> Option<&dyn Fail> {
        self.value.cause()
    }

    fn backtrace(&self) -> Option<&Backtrace> {
        self.value.backtrace()
    }
}

// 打包类型错误
#[derive(Debug, Fail)]
pub enum PackErrorValue {
    // 头部信息不存在
    #[fail(display = "not exist header")]
    NotExistHeader,
    // 未知的读取状态
    #[fail(display = "unknow read state")]
    UnknowReadState,
    // 字节写入错误
    #[fail(display = "bytes writer error: {}", _0)]
    BytesWriteError(BytesWriteError),
}

#[derive(Debug)]
pub struct PackError {
    pub value: PackErrorValue,
}

// 实现从 'PackErrorValue' 到 'PackError' 的转换
impl From<PackErrorValue> for PackError {
    fn from(value: PackErrorValue) -> Self {
        PackError { value }
    }
}

// 实现从 'BytesWriteError' 到 'PackError' 的转换
impl From<BytesWriteError> for PackError {
    fn from(error: BytesWriteError) -> Self {
        PackError {
            value: PackErrorValue::BytesWriteError(error),
        }
    }
}

// 实现 'fmt::Display' trait，用于格式化 'PackError' 的输出
impl fmt::Display for PackError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(&self.value, f)
    }
}

// 实现 'Fail' trait，用于错误处理链
impl Fail for PackError {
    fn cause(&self) -> Option<&dyn Fail> {
        self.value.cause() // 返回内部错误的根本原因
    }

    fn backtrace(&self) -> Option<&Backtrace> {
        self.value.backtrace() // 返回内部错误的回溯信息
    }
}
